v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
// 模型空间转到世界空间
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
// 法线向量归一化
o.worldNormal = normalize(UnityObjectToWorldNormal(v.normal));
return o;
}
在像素着色器中,首先通过世界坐标拿到光照的方向,也就是所谓的入射光,用法线点乘入射光,就可以得到入射光与模型表面的夹角,由于当入射光和法线夹角的余弦值为负数的时候,所得到的结果始终都是零,就会导致照不到的地方一片漆黑,所以这里需要乘0.5再加0.5 ,这样就可以把原本-1到1的取值范围变为0-1的取值范围。最后把求出来的光照亮度叠加到最终的像素色彩值就可以啦
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// 得到光照方向
float3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
// NoL代表表面接受的能量大小
float NoL = dot(i.worldNormal, worldLightDir);
// 计算half-lambert亮度值
float halfLambert = NoL * 0.5 + 0.5;
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col * halfLambert;
}
这样最终的效果就会更符合我们的视觉观感。
|